﻿using System;
using System.Windows.Forms;
using Fiddler;
using FiddlerAmfParser.Controls;
using FiddlerAmfParser.OutputProcessing;
using FiddlerAmfParser.Rendering;
using StructureMap;

namespace FiddlerAmfParser.AmfInspectors
{
	public abstract class AmfInspectorBase : Inspector2
	{
		protected byte[] BodyData;
		protected AmfOutputControl AmfOutput;
		protected bool IsAmfContent;
		protected AmfRenderer Renderer;
		protected HTTPHeaders HeaderData;

		protected AmfInspectorBase()
		{
			IsAmfContent = false;
		}

		// ReSharper disable InconsistentNaming
		public bool bReadOnly { get; set; }
		public bool bDirty { get; private set; }
		// ReSharper restore InconsistentNaming

		// ReSharper disable InconsistentNaming
		public abstract byte[] body { get; set; }
		// ReSharper restore InconsistentNaming

		protected bool DisableContentTypeCheck { get; set; }

		public override int GetOrder()
		{
			return 0;
		}

		public void Clear()
		{
			IsAmfContent = false;
			bDirty = false;
		}

		public override void AddToTab(TabPage tabPage)
		{
			ObjectFactory.Initialize(exp => exp.AddRegistry<PluginRegistry>());
			var processorPlugins = ObjectFactory.GetAllInstances<IOutputProcessorPlugin>();
			Renderer = new AmfRenderer(processorPlugins);
			
			AmfOutput = new AmfOutputControl();
			tabPage.Text = Constants.TabName;
			tabPage.Controls.Add(AmfOutput);
			AmfOutput.Dock = DockStyle.Fill;

			// Update DisableContentType check on CheckedChanged
			AmfOutput.DisableContentTypeCheck.CheckedChanged += OnDisableContentTypeCheckOnCheckedChanged;
		}

		private void OnDisableContentTypeCheckOnCheckedChanged(object sender, EventArgs args)
		{
			DisableContentTypeCheck = AmfOutput.DisableContentTypeCheck.Checked;
			AmfOutput.StatusBox.AppendText("Reload content or change tab that the change have an effect on the output.\r\n");
		}

		protected byte[] DecodeBodyIfRequired(byte[] value)
		{
			if ((HeaderData.Exists("Transfer-Encoding") || HeaderData.Exists("Content-Encoding")))
			{
				// Create a copy of the body to avoid corrupting the original
				var arrCopy = (byte[]) value.Clone();
				Utilities.utilDecodeHTTPBody(HeaderData, ref arrCopy);
				return arrCopy;
			}

			return value;
		}
	}
}